﻿using MyAlbum.Services;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using System;
using MyAlbum.Model;
using PersonalAlbum.Exceptions;
namespace UnitTests
{


    /// <summary>
    ///This is a test class for EntryServiceTest and is intended
    ///to contain all EntryServiceTest Unit Tests
    ///</summary>
    [TestClass()]
    public class EntryServiceTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }


        [TestInitialize()]
        public void MyTestInitialize()
        {
            _testConfig = new TestConfig();
            entries = new List<MyAlbum.Model.Entry>();
            //first clear all the old items
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var oldItems = this.Service.GetItems();
            foreach (var item in oldItems)
            {
                this.Service.DeleteItem(item);
            }
        }
        //
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            _testConfig.Dispose();
            foreach (var item in entries)
            {
                Service.DeleteItem(item);
            }
        }
        //
        private TestConfig _testConfig;
        private List<MyAlbum.Model.Entry> entries;
        MyAlbum.Services.EntryService Service
        {
            get
            {
                return ObjectFactory.GetInstance<IEntryService>() as EntryService;
            }
        }


        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e,new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);
            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            int id = e.Id;
            e = Create();
            e.Id = id;
            target.UpdateItem(e, new MyAlbum.Utility.GenericValidationSummary());
          
            saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Null_Description()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);
            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            int id = e.Id;
            e = Create();
            e.Description = null;

            e.Id = id;
            target.UpdateItem(e, new MyAlbum.Utility.GenericValidationSummary());
            saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            saved.Description = string.Empty;
            Compare(e, saved);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Null_ThumbUri()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);
          

            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            int id = e.Id;
            e = Create();
            e.ThumbUri = null;

            e.Id = id;
            target.UpdateItem(e, new MyAlbum.Utility.GenericValidationSummary());
            saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);

            saved.ThumbUri = string.Empty;
            Compare(e, saved);
        }


        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void UpdateItem_Null_Item()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            target.UpdateItem(null, new MyAlbum.Utility.GenericValidationSummary());
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Null_Uri()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);
          

            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            int id = e.Id;
            e = Create();
            e.Uri = null;

            e.Id = id;
            target.UpdateItem(e, new MyAlbum.Utility.GenericValidationSummary());
            saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);

            saved.Uri = string.Empty;
            Compare(e, saved);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Null_Title()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);
         

            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            int id = e.Id;
            e = Create();
            e.Title = null;

            e.Id = id;
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.UpdateItem(e,v);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Title", v.Errors.Keys.First());
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]       
        public void UpdateItem_Bad_ID_Should_Not_Crash()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            target.UpdateItem(new Entry() { Id = -1 * new Random().Next() }, new MyAlbum.Utility.GenericValidationSummary());
        }

        /// <summary>
        ///A test for GetLatestEntry
        ///</summary>
        [TestMethod()]
        public void GetLatestEntryTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
          
            var actual = target.GetLatestEntry();
            Compare(e1, actual);
        }

        /// <summary>
        ///A test for GetLatestEntry
        ///</summary>
        [TestMethod()]
        public void GetLatestEntry_Visible_Only()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetLatestEntry();
            Compare(e, actual);
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Visible_Only()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetItems();
            var loaded = actual.SingleOrDefault(i => i.Id == e.Id);
            Assert.IsNotNull(loaded);
            Compare(e, loaded);
            loaded = actual.SingleOrDefault(i => i.Id == e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);
            loaded = actual.SingleOrDefault(i => i.Id == e1.Id);
            Assert.IsNull(loaded);
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Not_Visible_Too()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
        

            var actual = target.GetItems();
            var loaded = actual.SingleOrDefault(i => i.Id == e.Id);
            Assert.IsNotNull(loaded);
            Compare(e, loaded);
            loaded = actual.SingleOrDefault(i => i.Id == e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);

            loaded = actual.SingleOrDefault(i => i.Id == e1.Id);
            Assert.IsNotNull(loaded);
            Compare(e1, loaded);

        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItems_Paging_Page1()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = true;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            var pageNumber = 1;
            var count = 4;
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetItems(pageNumber, count);
            Assert.IsNotNull(actual);
            Assert.AreEqual(count, actual.Count);
            for (int i = (pageNumber - 1) * count; i < (pageNumber * count); i++)
            {
                var e = this.entries[i];
                var saved = actual.SingleOrDefault(j => j.Id == e.Id);
                Assert.IsNotNull(saved);
                Compare(e, saved);
            }
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItems_Paging_Page2()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = true;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            var pageNumber = 2;
            var count = 4;
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetItems(pageNumber, count);
            Assert.IsNotNull(actual);
            Assert.AreEqual(count, actual.Count);
            for (int i = (pageNumber - 1) * count; i < (pageNumber * count); i++)
            {
                var e = this.entries[i];
                var saved = actual.SingleOrDefault(j => j.Id == e.Id);
                Assert.IsNotNull(saved);
                Compare(e, saved);
            }
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItems_Paging_Non_Existent_Page_Number()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = true;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            var pageNumber = 20;
            var count = 4;
             user = new GenericUser("tal", new string[] { "" });
             ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
             var actual = target.GetItems(pageNumber, count);
            Assert.IsNotNull(actual);
            Assert.AreEqual(0, actual.Count);

        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Not_Visible_Too_Default_Value()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetItems();//default is true
            var loaded = actual.SingleOrDefault(i => i.Id == e.Id);
            Assert.IsNotNull(loaded);
            Compare(e, loaded);
            loaded = actual.SingleOrDefault(i => i.Id == e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);

            loaded = actual.SingleOrDefault(i => i.Id == e1.Id);
            Assert.IsNull(loaded);


        }



        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetItemByIdTest_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);

            var loaded = target.GetItemById(e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetItemByIdTest_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = false;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);

           
            user = new GenericUser("tal", new string[] { "User" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var loaded = target.GetItemById(e0.Id);
            Assert.IsNull(loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetEntryById_Entry_Not_Visible_Param_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = false;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);

            var loaded = target.GetItemById(e0.Id);
            Assert.IsNull(loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetEntryById_Entry_Visible_Param_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);

            var loaded = target.GetItemById(e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetEntryById_Entry_Visible_Param_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = true;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
          
            var loaded = target.GetItemById(e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetEntryById_Entry_Not_Visible_Param_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e);

            Entry e0 = Create();
            e0.Visible = false;
            target.AddItem(e0, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e0);

            Entry e1 = Create();
            target.AddItem(e1, new MyAlbum.Utility.GenericValidationSummary());
            entries.Add(e1);
           
            var loaded = target.GetItemById(e0.Id);
            Assert.IsNotNull(loaded);
            Compare(e0, loaded);
        }

        /// <summary>
        ///A test for GetEntriesCount
        ///</summary>
        [TestMethod()]
        public void GetEntriesCountTest_Visible_And_Param_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = true;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            var actual = target.GetEntriesCount(true);
            Assert.AreEqual(20, actual);
        }


        /// <summary>
        ///A test for GetEntriesCount
        ///</summary>
        [TestMethod()]
        public void GetEntriesCountTest_Not_Visible_And_Param_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            } 
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetEntriesCount(true);
            Assert.AreEqual(0, actual);
        }

        /// <summary>
        ///A test for GetEntriesCount
        ///</summary>
        [TestMethod()]
        public void GetEntriesCountTest_Visible_And_Param_Not_Visible()
        {
          var  user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = true;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetEntriesCount(false);
            Assert.AreEqual(20, actual);
        }

        /// <summary>
        ///A test for GetEntriesCount
        ///</summary>
        [TestMethod()]
        public void GetEntriesCountTest_Not_Visible_And_Param_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;

            for (int i = 0; i < 20; i++)
            {
                Entry e = Create();
                e.Visible = false;
                target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
                entries.Add(e);
            }
            var actual = target.GetEntriesCount(false);
            Assert.AreEqual(20, actual);
        }

        /// <summary>
        ///A test for GetEntriesByTagName
        ///</summary>
        [TestMethod()]
        public void Tag_Test_Check_That_Tags_Are_Deleted_After_Entry_Delete()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
            target.DeleteItem(e);
            saved = target.GetItems().SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNull(saved);
            var tags = ObjectFactory.GetInstance<ITagEntryService>().GetTags().Select(t => t.Name).ToList();
            foreach (var item in e.Tags)
            {
                Assert.IsFalse(tags.Contains(item.Name));
            }
        }

        /// <summary>
        ///A test for GetEntriesByTagName
        ///</summary>
        [TestMethod()]
        public void GetEntriesByTagName_Visible_Parameter_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
             user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);

            var saved = target.GetEntriesByTagName(e.Tags.First().Name).SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
        }

        /// <summary>
        ///A test for GetEntriesByTagName
        ///</summary>
        [TestMethod()]
        public void GetEntriesByTagName_Visible_Parameter_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
           

            var saved = target.GetEntriesByTagName(e.Tags.First().Name).SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
        }

        /// <summary>
        ///A test for GetEntriesByTagName
        ///</summary>
        [TestMethod()]
        public void GetEntriesByTagName_Not_Visible_Parameter_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = false;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            

            var saved = target.GetEntriesByTagName(e.Tags.First().Name).SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
            Compare(e, saved);
        }

        /// <summary>
        ///A test for GetEntriesByTagName
        ///</summary>
        [TestMethod()]
        public void GetEntriesByTagName_Not_Visible_Regular_User()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = false;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var saved = target.GetEntriesByTagName(e.Tags.First().Name).SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNull(saved);
        }

        [TestMethod()]
        public void GetEntriesByTagName_Not_Visible_Power_User()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = false;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            user = new GenericUser("tal", new string[] {RolesManager.PowerUser });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var saved = target.GetEntriesByTagName(e.Tags.First().Name).SingleOrDefault(en => en.Id == e.Id);
            Assert.IsNotNull(saved);
        }

        /// <summary>
        ///A test for GetEntriesByAlbum
        ///</summary>
        [TestMethod()]
        public void dGetEntriesByAlbumTest_Visible_Page1()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            var albumId = e.AlbumId;
            e.Visible = true;

            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id1 = e.Id;
            e = Create();
            e.AlbumId = albumId;
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id2 = e.Id;
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetEntriesByAlbum(albumId, 1, 5);
            Assert.IsNotNull(actual);
            Assert.AreEqual(2, actual.Count);
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id1));
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id2));

        }

        /// <summary>
        ///A test for GetEntriesByAlbum
        ///</summary>
        [TestMethod()]
        public void GetEntriesByAlbumTest_Not_Visible()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            var albumId = e.AlbumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id1 = e.Id;
            e = Create();
            e.AlbumId = albumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id2 = e.Id;
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetEntriesByAlbum(albumId, 1, 5);
            Assert.IsNotNull(actual);
            Assert.AreEqual(0, actual.Count);

        }

        /// <summary>
        ///A test for GetEntriesByAlbum
        ///</summary>
        [TestMethod()]
        public void GetEntriesByAlbum_Not_Visible_Param_Not_Visible_With_Paging()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            var albumId = e.AlbumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id1 = e.Id;
            e = Create();
            e.AlbumId = albumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id2 = e.Id;
           
            var actual = target.GetEntriesByAlbum(albumId, 1, 5);
            Assert.IsNotNull(actual);
            Assert.AreEqual(2, actual.Count);
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id1));
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id2));

        }

        /// <summary>
        ///A test for GetEntriesByAlbum
        ///</summary>
        [TestMethod()]
        public void GetEntriesByAlbum_Invalid_Page_Number()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            var albumId = e.AlbumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id1 = e.Id;
            e = Create();
            e.AlbumId = albumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id2 = e.Id;
          

            var actual = target.GetEntriesByAlbum(albumId, 2, 5);
            Assert.IsNotNull(actual);
            Assert.AreEqual(0, actual.Count);

        }

        /// <summary>
        ///A test for GetEntriesByAlbum
        ///</summary>
        [TestMethod()]
        public void GetEntriesByAlbumTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            var albumId = e.AlbumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id1 = e.Id;
            e = Create();
            e.Visible = true;

            e.AlbumId = albumId;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());
            var id2 = e.Id;
            var actual = target.GetEntriesByAlbum(albumId);
            Assert.IsNotNull(actual);
            Assert.AreEqual(2, actual.Count);
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id1));
            Assert.IsNotNull(actual.SingleOrDefault(en => en.Id == id2));
        }

        /// <summary>
        ///A test for DeleteItem
        ///</summary>
        [TestMethod()]
        public void DeleteItemTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());

            Entry e2 = Create();
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());
          
            Assert.IsNotNull(target.GetItemById(e.Id));
            Assert.IsNotNull(target.GetItemById(e2.Id));

            target.DeleteItem(e);
            Assert.IsNull(target.GetItemById(e.Id));
            Assert.IsNotNull(target.GetItemById(e2.Id));

        }

        [TestMethod()]
        public void DeleteItemTest_Unauthorized_User()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Visible = true;
            this.entries.Add(e);
            target.AddItem(e, new MyAlbum.Utility.GenericValidationSummary());

            Entry e2 = Create();
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());

            Assert.IsNotNull(target.GetItemById(e.Id));
            Assert.IsNotNull(target.GetItemById(e2.Id));
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            target.DeleteItem(e);
            Assert.IsNotNull(target.GetItemById(e.Id));
            Assert.IsNotNull(target.GetItemById(e2.Id));

        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e2 = Create();
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());
           

            var actual = target.GetItemById(e2.Id);
            Assert.IsNotNull(actual);
            Compare(e2, actual);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void AddItem_Null_Item()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            target.AddItem(null, new MyAlbum.Utility.GenericValidationSummary());
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Null_ThumbURI()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e2 = Create();
            e2.ThumbUri = null;
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());
            
            var actual = target.GetItemById(e2.Id);
            Assert.IsNotNull(actual);
            Compare(e2, actual);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Null_URI()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e2 = Create();
            e2.Uri = null;
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());
            
            var actual = target.GetItemById(e2.Id);
            Assert.IsNotNull(actual);
            Compare(e2, actual);
        }

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Null_Description()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e2 = Create();
            e2.Description = null;
            e2.Visible = true;
            this.entries.Add(e2);
            target.AddItem(e2, new MyAlbum.Utility.GenericValidationSummary());
         
            var actual = target.GetItemById(e2.Id);
            Assert.IsNotNull(actual);
            Compare(e2, actual);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Null_Title()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var target = this.Service;
            Entry e = Create();
            e.Title = null;
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(e,v);
            entries.Add(e);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Title", v.Errors.Keys.First());
        }

        /// <summary>
        ///A test for EntryService Constructor
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void EntryServiceConstructorTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Data.IEntryRepository entryRepository = null;

            MyAlbum.Services.EntryService target = new MyAlbum.Services.EntryService(entryRepository,null,null);
        }

        private void Compare(Entry expected, Entry actual)
        {
            if (expected == null)
            {
                Assert.IsNull(actual);

            }
            else if (actual == null)
            {
                Assert.IsNull(expected);
            }
            Assert.AreEqual(expected.AlbumId, actual.AlbumId);
            Assert.AreEqual(expected.Description ?? string.Empty, actual.Description ?? string.Empty);
            Assert.AreEqual(expected.EntryType, actual.EntryType);
            Assert.AreEqual(expected.FileSize, actual.FileSize);
            Assert.AreEqual(expected.Height, actual.Height);
            Assert.AreEqual(expected.ThumbHeight, actual.ThumbHeight);
            Assert.AreEqual(expected.ThumbUri ?? string.Empty, actual.ThumbUri ?? string.Empty);
            Assert.AreEqual(expected.ThumbWidth, actual.ThumbWidth);
            Assert.AreEqual(expected.Title ?? string.Empty, actual.Title ?? string.Empty);
            Assert.AreEqual(expected.Uri ?? string.Empty, actual.Uri ?? string.Empty);
            Assert.AreEqual(expected.VideoLen, actual.VideoLen);
            Assert.AreEqual(expected.Visible, actual.Visible);
            Assert.AreEqual(expected.Width, actual.Width);
            Assert.IsNotNull(actual.Tags);
            if (expected.Tags != null)
            {
                List<string> names = actual.Tags.Select(t => t.Name).ToList();
                foreach (var item in expected.Tags)
                {
                    Assert.IsTrue(names.Contains(item.Name));
                }
            }
            if (expected.Replies != null)
            {
                Assert.IsNotNull(actual.Replies);
                foreach (var item in actual.Replies)
                {
                    var e = expected.Replies.SingleOrDefault(r => r.Id == item.Id);
                    Assert.IsNotNull(e);
                    Assert.AreEqual(e.Body, item.Body);
                    Assert.AreEqual(e.Email, item.Email);
                    Assert.AreEqual(e.EntryId, item.EntryId);
                    Assert.AreEqual(e.IsApproved, item.IsApproved);
                    Assert.AreEqual(e.Subject, item.Subject);
                    Assert.AreEqual(e.UserName, item.UserName);
                }
            }
        }

        public static Entry Create()
        {
            Entry e = new Entry()
            {
                AlbumId = new Random().Next(),
                Date = DateTime.Now,
                Description = Guid.NewGuid().ToString(),
                EntryType = new Random().Next(),
                Height = new Random().Next(),
                ThumbHeight = new Random().Next(),
                ThumbUri = Guid.NewGuid().ToString(),
                ThumbWidth = new Random().Next(),
                Title = Guid.NewGuid().ToString(),
                Uri = Guid.NewGuid().ToString(),
                Visible = false,
                Width = new Random().Next(),
                Tags = new List<Tag>(){
                    new Tag(){ Name=Guid.NewGuid().ToString().Substring(0,10)},
                    new Tag(){Name=Guid.NewGuid().ToString().Substring(0,10)}},

            };
            return e;
        }

        private void AddReplies(Entry e)
        {
            e.Replies = new List<Reply>()
                {
                    new Reply(){
                         UserName=Guid.NewGuid().ToString(),
                          Subject=Guid.NewGuid().ToString(),
                           IsApproved=new Random().Next()%2==0,
                             Body=Guid.NewGuid().ToString(),
                              Email=Guid.NewGuid().ToString(),
                               TimeStamp=DateTime.Now},
                    new Reply(){
                         UserName=Guid.NewGuid().ToString(),
                          Subject=Guid.NewGuid().ToString(),
                           IsApproved=new Random().Next()%2==0,
                             Body=Guid.NewGuid().ToString(),
                              Email=Guid.NewGuid().ToString(),
                               TimeStamp=DateTime.Now}
                                
                };
        }
    }
}
